package it.allerj.common.persistence.clientSide;


import it.allerj.common.persistence.HibernateConfigHolder;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;



public class PersistenceClientHome {
protected static ThreadLocal<HibernateConfigHolder> hibernateHolder = new ThreadLocal<HibernateConfigHolder>( ); 
    
    protected static SessionFactory factory;

    public static void doInit( ) throws HibernateException {
        if(factory==null)
            factory = new Configuration( ).configure( ).buildSessionFactory( );
        allocateThreadLocal();
        System.out.println("Sessione aperta!");
    }
    private static void allocateThreadLocal() {
    	if (hibernateHolder.get( ) != null)
            throw new IllegalStateException(
                "A session is already associated with this thread!  "
                + "Someone must have called getSession( ) outside of the context "
                + "of a servlet request.");
        getSession(); 
    }
    
	@SuppressWarnings("unchecked")
	public static Session getSession( ) throws HibernateException {
        
    	 
        //-----------------------
        HibernateConfigHolder hch = hibernateHolder.get();
        if (hch == null) {
            hch = new HibernateConfigHolder();
            Session sess = factory.openSession();
            Transaction tran = sess.beginTransaction();
            hch.setSession(sess);
            hch.setTransaction(tran);
            hibernateHolder.set(hch);
            //System.out.println("APRO LA CONNESSIONE");
        }
       
        
        //transaction = sess.beginTransaction();
        return hch.getSession();
    }
  
 
    public static SessionFactory getSessionFactory( ) {
      return factory;
    }
  public static void checkPoint() {
    HibernateConfigHolder hch = hibernateHolder.get();
    if (hch != null) {
      hch.getTransaction().commit();
      
      //Marco: Inizio una nuova transazione
      Transaction tran = hch.getSession().beginTransaction();
      hch.setTransaction(tran);
      //-----------

    }
  }
    public static void rollback(Transaction tx) {
        if (tx != null) {
            try {
                tx.rollback( );
            }
            catch (HibernateException ex) {
                // Probably don't need to do anything - this is likely being
                // called because of another exception, and we don't want to
                // mask it with yet another exception.
            }
        }
    }

    public void destroy( ) {
        // Nothing necessary
    }
   

    public static ThreadLocal<HibernateConfigHolder> getHibernateHolder() {
        return hibernateHolder;
    }
    @SuppressWarnings("unchecked")
	public static void closeAll() throws Exception {
    	HibernateConfigHolder hch = hibernateHolder.get( );
        if(hch!=null){
            hibernateHolder.set(null);
            try {
            	//System.out.println("CHIUDO LA CONNESSIONE");
                hch.getTransaction().commit();
                hch.getSession().close();
                hch.setSession(null);
                hch.setTransaction(null);
            }
            /*catch (HibernateException ex) { 
                throw new Exception(ex);
            }*/
            catch (Throwable ex) { 
                throw new Exception(ex);
            }
        }
        System.out.println("Sessione chiusa!");
    }
    public static void commitAndClose() {
  		HibernateConfigHolder hch = hibernateHolder.get();
  		if (hch != null) {
  			hibernateHolder.set(null);
  			try {
  				hch.getTransaction().commit();
  				if(hch.getSession().isOpen())
  					hch.getSession().close();
  				hch.setSession(null);
  				hch.setTransaction(null);
  			} catch (HibernateException ex) {
  				try{
  					hch.getTransaction().rollback();
  				} catch (Exception e){
  					e.printStackTrace();
  					if(hch.getSession().isOpen())
  						hch.getSession().close();
  					hch.setSession(null);
  					hch.setTransaction(null);
  					return;
  				}
  				hch.getSession().close();
  				hch.setSession(null);
  				hch.setTransaction(null);
  			}
  		}
  	}
    public static void checPoint() {
    	HibernateConfigHolder hch = hibernateHolder.get();
  		if (hch != null) {
  			hch.getTransaction().commit();
  			Transaction tran = hch.getSession().beginTransaction();
  			hch.setTransaction(tran);
  		}
    }
}
